package com.fingard.dsp.bank.directbank.gxnx01;

import java.net.URLDecoder;
import java.text.DecimalFormat;
import java.util.Date;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.directbank.fngrd01.util.StringHelper;
import com.fingard.net.ITcpClient;
import com.fingard.net.TcpPortClient;
import com.fingard.net.TcpReceiver;
import com.fingard.net.WebRequest;
import com.fingard.util.TransIDHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * Created by F on 2018/10/10.
 */
public class GXNX01Base extends DirectBase implements ITcpClient {
    private static final String STR_FORMAT = "00000000";
    DecimalFormat decimalFormat = new DecimalFormat(STR_FORMAT);

    public void getContentLength(TcpReceiver p_receiver) throws Exception {
        if (p_receiver.contentLength == -1) {
            if (p_receiver.readedLength >= 8) {
                String tmpHead = new String(p_receiver.recBytes, 0, 8, getCharset2());
                WriteBankLogStep3(tmpHead);
                p_receiver.contentLength = Integer.parseInt(tmpHead.trim())-8;
                p_receiver.contentStartIndex = 0;
            }
        }
    }
    private static TransIDHelper idHelper = new TransIDHelper(1, 99999);

    protected String getQryTransID() {
        Date tmpDateNow = new Date();
        return Format.Time9Format.format(tmpDateNow).substring(6)+ idHelper.getNextIDStr();
    }

    protected String getCharset() {
        return "UTF-8";
    }

    protected String getCharset2() {
        return "GB2312";
    }

    protected void writeCommonHeader(XmlTextWriter xmlWriter, GXNX01Header p_bankHeader) throws Exception {
        xmlWriter.writeStartDocByDeclaration(p_bankHeader.tranCode+"|#<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        xmlWriter.writeStartElement("QLBankData");
        xmlWriter.writeStartElement("opReq");
        xmlWriter.writeElementString("bsnCode", p_bankHeader.tranCode);//交易码
        xmlWriter.writeElementString("cstNo", bankFront.userName);//客户号
        Date date = new Date();
        xmlWriter.writeElementString("reqTime", Format.DateTime14Format.format(date));//请求时间
    }

    /**
     * http post请求到银行
     * @param p_reqStr
     * @return
     * @throws Exception
     */
    protected String[] sendToBank(String p_reqStr) throws Exception{
        //广西农信银行系统设定的报文格式前面不能是空格
        p_reqStr=p_reqStr.substring(0,p_reqStr.indexOf("?>")+2)+p_reqStr.substring(p_reqStr.indexOf("?>")+2).replaceAll(" ","");
        String[] retStr = new String[]{"", ""};
        String charset=getCharset2();//gbk
        WriteBankLogLn("1.提交银行的地址：" + bankFront.serverURL);
        int n = p_reqStr.getBytes(charset).length;
        String p_head = decimalFormat.format(n);
        String p_string = p_reqStr;
        WriteBankLogStep2(p_string);
        WebRequest tmpWebRequest = new WebRequest(bankFront.serverURL);
        tmpWebRequest.setConnectTimeout(60000);
        //tmpWebRequest.setRequestProperty("Content-Type", "application/json");
        tmpWebRequest.setRequestProperty("content-type", "text/xml; charset="+charset);
        tmpWebRequest.setRequestProperty("connection", "Close");
        String charsetName = charset;
        byte[] tmpToWriteBytes = p_string.getBytes(charsetName);
        retStr = tmpWebRequest.upload(tmpToWriteBytes, charsetName);
        WriteBankLogLn("银行返回的原文："+retStr[1]);
        //解密返回的报文
        retStr[1]=URLDecoder.decode(retStr[1].toString(),"UTF-8").toString();
        WriteBankLogStep3(retStr[1]);
        return retStr;
    }

    /**
     * tcp/ip 请求到前置机
     * @param p_reqStr
     * @return
     * @throws Exception
     */
    protected String[] sendToBankBySign(String p_reqStr) throws Exception{
        String[] retStr = new String[]{"", ""};
        WriteBankUrlLogLn( "请求银行的地址"+bankFront.serverIP + ":" + bankFront.serverPort);
        WriteBankLogLn("发送至银行的请求报文："+p_reqStr);
        //发送银行前置
        TcpPortClient tmpClient = new TcpPortClient(bankFront.serverIP, Integer.parseInt(bankFront.serverPort), this);
        TcpReceiver tmpReceiver = tmpClient.sendMessage(p_reqStr,getCharset2());
        retStr[0] = tmpReceiver.connState;
        retStr[1] = tmpReceiver.getFullString(getCharset2());
        if(StringHelper.isNullOrEmpty(retStr[1])){
        	retStr[1] = tmpReceiver.getConnMsg();
        }
        WriteBankLogLn(retStr[1]);
        return retStr;
    }

    /**
     * 请求获取签名后的数据报文
     * @param xmlWriter
     * @param origin_data
     * @throws Exception
     */
    protected void writeHeaderAndBody(XmlTextWriter xmlWriter, String origin_data) throws Exception {
        xmlWriter.writeStartDocByDeclaration("<?xml version='1.0' encoding='gb2312'?>");
        xmlWriter.writeStartElement("msg");
        xmlWriter.writeStartElement("msg_head");
        xmlWriter.writeElementString("msg_type", "0");
        xmlWriter.writeElementString("msg_id", "1005");
        xmlWriter.writeElementString("msg_sn", "0");
        xmlWriter.writeElementString("version", "1");
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("msg_body");
        xmlWriter.writeElementString("origin_data_len", String.valueOf(origin_data.trim().getBytes().length));
        xmlWriter.writeElementString("origin_data", origin_data.trim());
        xmlWriter.writeEndElement();
        xmlWriter.writeEndDocument();
    }

    /**
     * 获取签名后的数据
     * @param signDataStr 签名原文
     * @return
     * @throws Exception
     */
    protected String sendBankBySigned(String signDataStr) throws Exception{
        String sign="";//定义签名后的数据
        try{
            XmlTextWriter xmlTextWriter2 = new XmlTextWriter();
            writeHeaderAndBody(xmlTextWriter2,signDataStr);
            String[] bankResult2 = sendToBankBySign(xmlTextWriter2.toXmlString());
            if (bankResult2[0].length() == 0) {
                StringBuilder tmpSb = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult2[1], tmpSb);
                if (tmpBkReader != null) {
                    //签名后的数据
                    sign=tmpBkReader.getFirstText("/msg/msg_body/signed_data");
                }
            }
        }catch (Exception e){
            WriteBankLogLn("获取签名后的数据异常:"+e);
        }
        //测试
        //sign = "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";
        return sign;
    }

    protected static boolean isActiveRetCode(String retCode) {
        if (retCode != null) {
            if (retCode.equals("0000")) {
                return true;
            }
        }
        return false;
    }
}
